﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.IO;
using Agresso.Interface.Layer.Domain;
using Agresso.Interface.Layer.Gateway;
using System.Data.SqlClient;
using Agresso.Interface.Layer.SQL;
using System.Xml;

namespace Agresso.Interface.Layer.Service
{
    public class InvoiceService
    {
        DataBaseConnectivity m_dataBaseConectivity;
        public InvoiceService()
        {
            m_dataBaseConectivity = new DataBaseConnectivity();
        }
        public void ImportDataFromXml()
        {
            try
            {
                string maxPostInvoiceFileFolder = ConfigurationManager.AppSettings["InvoiceFileFolder"];
                string maxPostInvoiceBackUpFileFolder = ConfigurationManager.AppSettings["InvoiceBackUpFileFolder"];
                string[] files = System.IO.Directory.GetFiles(maxPostInvoiceFileFolder);
                foreach (string file in files)
                {
                    string ext = Path.GetExtension(file);
                    if (ext.ToLower() != ".xml") continue;
                    Invoice result = null;

                    DeleteLogFile(file + "_log.log");
                    try
                    {
                        result = ReadFormXMLFile(file);
                    }
                    catch (Exception x)
                    {
                        CreateLogFile(file + "_log.log", DateTime.Now + " : " + x.Message);
                    }
                    if (result != null)
                    {
                        InsertToDB(result);
                        string destinationFile = maxPostInvoiceBackUpFileFolder + file.Substring(file.LastIndexOf("\\") + 1);
                        File.Move(file, AssertFileExist(maxPostInvoiceBackUpFileFolder, destinationFile));
                    }
                }
            }
            catch (Exception x)
            {
                throw x;
            }
        }
        public string AssertFileExist(string destinationFolder, string file)
        {
            if (File.Exists(file))
            {
                string fileName = file.Substring(file.LastIndexOf("\\") + 1);
                string[] files = fileName.Split('.');
                string file1 = files[0];
                string file2 = files[1];
                file = destinationFolder + file1 + "_Copy." + file2;
                file = AssertFileExist(destinationFolder, file);
                return file;
            }
            return file;
        }
        public void DeleteLogFile(string fileName)
        {
            if (File.Exists(fileName))
                File.Delete(fileName);
        }
        public void CreateLogFile(string fileName, string log)
        {
            StreamWriter file = new StreamWriter(fileName);
            file.WriteLine(log);
            file.Close();
        }
        private void InsertToDB(Invoice result)
        {
            try
            {
                m_dataBaseConectivity.InterfaceSqlConnection.Open();
                SqlCommand cmd = new SqlCommand(InvoiceSQL.InsertInvoice(), m_dataBaseConectivity.InterfaceSqlConnection);
                if (result.LineItems.Count == 0)
                    result.LineItems.Add(result);
                foreach (Invoice item in result.LineItems)
                {
                    cmd.Parameters.Clear(); 
                    cmd.Parameters.Add("@FileName", System.Data.SqlDbType.NVarChar).Value = item.FileName;
                    cmd.Parameters.Add("@Client", System.Data.SqlDbType.NVarChar).Value = item.Client;
                    cmd.Parameters.Add("@CompanyCode", System.Data.SqlDbType.NVarChar).Value = item.CompanyCode;
                    cmd.Parameters.Add("@SupplierId", System.Data.SqlDbType.NVarChar).Value = item.SupplierId;
                    cmd.Parameters.Add("@SupplierName", System.Data.SqlDbType.NVarChar).Value = item.SupplierName;
                    cmd.Parameters.Add("@VatId", System.Data.SqlDbType.NVarChar).Value = item.VatId;
                    cmd.Parameters.Add("@TaxNo", System.Data.SqlDbType.NVarChar).Value = item.TaxNo;
                    cmd.Parameters.Add("@Scandate", System.Data.SqlDbType.DateTime).Value = item.Scandate;
                    cmd.Parameters.Add("@DocumentType", System.Data.SqlDbType.NVarChar).Value = item.DocumentType;
                    cmd.Parameters.Add("@InvoiceDate", System.Data.SqlDbType.DateTime).Value = item.InvoiceDate;
                    cmd.Parameters.Add("@InvoiceNumber", System.Data.SqlDbType.NVarChar).Value = item.InvoiceNumber;
                    cmd.Parameters.Add("@Netamount", System.Data.SqlDbType.Decimal).Value = item.Netamount;
                    cmd.Parameters.Add("@Vatrate", System.Data.SqlDbType.Decimal).Value = item.Vatrate;
                    cmd.Parameters.Add("@Vatamount", System.Data.SqlDbType.Decimal).Value = item.Vatamount;
                    cmd.Parameters.Add("@Totalamount", System.Data.SqlDbType.Decimal).Value = item.Totalamount;
                    cmd.Parameters.Add("@Currency", System.Data.SqlDbType.NVarChar).Value = item.Currency;
                    cmd.Parameters.Add("@line_no", System.Data.SqlDbType.NVarChar).Value = item.line_no;
                    cmd.Parameters.Add("@PONo", System.Data.SqlDbType.NVarChar).Value = item.PONo;
                    cmd.Parameters.Add("@POPosition", System.Data.SqlDbType.NVarChar).Value = item.POPosition;
                    cmd.Parameters.Add("@Description", System.Data.SqlDbType.NVarChar).Value = item.Description;
                    cmd.Parameters.Add("@DeliveryNoteNo", System.Data.SqlDbType.NVarChar).Value = item.DeliveryNoteNo;
                    cmd.Parameters.Add("@Total", System.Data.SqlDbType.Decimal).Value = item.Total;
                    cmd.Parameters.Add("@Quantity", System.Data.SqlDbType.Decimal).Value = item.Quantity;
                    cmd.Parameters.Add("@Unitprice", System.Data.SqlDbType.Decimal).Value = item.Unitprice;
                    cmd.Parameters.Add("@Unit", System.Data.SqlDbType.NVarChar).Value = item.Unit;
                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception x)
            {
                throw x;
            }
            finally
            {
                m_dataBaseConectivity.InterfaceSqlConnection.Close();
            }
        }
        private Invoice ReadFormXMLFile(string xmlFile)
        {
            Invoice mHeader = null;
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(xmlFile);
                XmlNodeList invoice = doc.SelectNodes("invoice");
                mHeader = new Invoice();
                mHeader.FileName = Path.GetFileName(xmlFile);
                XmlNodeList header = invoice[0].SelectNodes("Header");
                mHeader.Client = header[0].SelectNodes("Client")[0].InnerText;
                mHeader.CompanyCode = header[0].SelectNodes("CompanyCode")[0].InnerText;
                mHeader.SupplierId = header[0].SelectNodes("SupplierId")[0].InnerText;
                mHeader.SupplierName = header[0].SelectNodes("SupplierName")[0].InnerText;
                mHeader.VatId = header[0].SelectNodes("VatId")[0].InnerText;
                mHeader.TaxNo = header[0].SelectNodes("TaxNo")[0].InnerText;
                mHeader.Scandate = Convert.ToDateTime(FixDateFormat(header[0].SelectNodes("Scandate")[0].InnerText));
                mHeader.DocumentType = header[0].SelectNodes("DocumentType")[0].InnerText;
                mHeader.InvoiceDate = Convert.ToDateTime(FixDateFormat(header[0].SelectNodes("InvoiceDate")[0].InnerText));
                mHeader.InvoiceNumber = header[0].SelectNodes("InvoiceNumber")[0].InnerText;
                mHeader.Netamount = Convert.ToDecimal(header[0].SelectNodes("Netamount")[0].InnerText);
                mHeader.Vatrate =  Convert.ToDecimal(header[0].SelectNodes("Vatrate")[0].InnerText==""?"0":header[0].SelectNodes("Vatrate")[0].InnerText);
                mHeader.Vatamount = Convert.ToDecimal(header[0].SelectNodes("Vatamount")[0].InnerText);
                mHeader.Totalamount = Convert.ToDecimal(header[0].SelectNodes("Totalamount")[0].InnerText);
                mHeader.Currency = header[0].SelectNodes("Currency")[0].InnerText;

                XmlNodeList positions = invoice[0].SelectNodes("Positions");
                XmlNodeList position = positions[0].SelectNodes("Position");

                foreach (XmlNode item in position)
                {
                    Invoice detail = new Invoice();
                    detail.line_no = item.SelectNodes("line_no")[0] == null ? "" : item.SelectNodes("line_no")[0].InnerText;
                    detail.PONo = item.SelectNodes("PONo")[0] == null ? "" : item.SelectNodes("PONo")[0].InnerText;
                    detail.POPosition = item.SelectNodes("POPosition")[0] == null ? "" : item.SelectNodes("POPosition")[0].InnerText;
                    detail.Description = item.SelectNodes("Description")[0] == null ? "" : item.SelectNodes("Description")[0].InnerText;
                    detail.DeliveryNoteNo = item.SelectNodes("DeliveryNoteNo")[0] == null ? "" : item.SelectNodes("DeliveryNoteNo")[0].InnerText;
                    detail.Total = Convert.ToDecimal(item.SelectNodes("Total")[0] == null ? "0" : item.SelectNodes("Total")[0].InnerText);
                    detail.Quantity = Convert.ToDecimal(item.SelectNodes("Quantity")[0] == null ? "0" : item.SelectNodes("Quantity")[0].InnerText);
                    detail.Unitprice = Convert.ToDecimal(item.SelectNodes("Unitprice")[0] == null ? "0" : item.SelectNodes("Unitprice")[0].InnerText);
                    detail.Unit = item.SelectNodes("Unit")[0] == null ? "" : item.SelectNodes("Unit")[0].InnerText;
                    mHeader.AddItem(detail);
                }
            }
            catch (Exception x)
            {
                LogService.WriteLogException(x);
                throw x;
            }
            return mHeader;
        }

        private string FixDateFormat(string date)
        {
            string result = "";
            string[] da = date.Split('.');
            result = da[2] + "-" + da[1] + "-" + da[0];
            return result;
        }
    }
}
